/*
 * Created on Feb 7, 2005
 * Created by dfhuynh
 */
package edu.mit.simile.longwell;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

import org.apache.log4j.Logger;

import com.hp.hpl.jena.db.IDBConnection;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.NodeIterator;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.vocabulary.RDF;

import edu.mit.simile.SimileUtilities;

/**
 * @author dfhuynh
 */
public abstract class LongwellUtilities {
	final static private Logger s_logger = 
		Logger.getLogger(SimileUtilities.class);
	
	static public void loadDataFromDir(File dir, Profile profile, boolean forgiving) throws IOException {
		if (!dir.exists()) {
			throw new FileNotFoundException("Cannot load data from " + dir.getAbsolutePath());
		}
		
		File[] files = dir.listFiles();
		
		for (int i = 0; i < files.length; i++) {
			File file = files[i];
			
			if (!file.isHidden()) {
				if (file.isDirectory()) {
					loadDataFromDir(file, profile, forgiving);
				} else {
					if (forgiving) {
						try {
							loadDataFromFile(file, profile);
						} catch (IOException e) {
							s_logger.warn(
								"Failed to load data from " + file.getAbsolutePath(),
								e
							);
						}
					} else {
						loadDataFromFile(file, profile);
					}
				}
			}
		}
	}
	
	static public void loadDataFromFile(File file, Profile profile) 
		throws IOException {
		
		Model model = ModelFactory.createDefaultModel();
		
		SimileUtilities.loadDataFromFile(file, model);
		
		if (model.size() > 0) {
			s_logger.info("Adding " + model.size() + " statements to profile " + profile.getID());
			profile.addData(model);
		}
		model.close();
	}

	
	static public Class getJavaImplementation(
		String modelURI, Model model
	) {
		Resource modelResource = model.createResource(modelURI);
		Property javaImplementationClassProperty =
			model.createProperty(
				Longwell.s_namespace + "javaImplementationClass");
		
		Statement stmt = 
			model.getProperty(modelResource, javaImplementationClassProperty);
		String className = null;
		
		if (stmt != null) {
			className = stmt.getString();
		
			try {
				return Class.forName(className);
			} catch (ClassNotFoundException e) {
			}
		}
		
		NodeIterator ni = model.listObjectsOfProperty(modelResource, RDF.type);
		while (ni.hasNext()) {
			RDFNode node = ni.nextNode();
			if (node instanceof Resource) {
				Resource type = (Resource) node;
				
				stmt = model.getProperty(type, javaImplementationClassProperty);
				if (stmt != null) {
					className = stmt.getString();
				
					try {
						return Class.forName(className);
					} catch (ClassNotFoundException e) {
					}
				}
			}
		}
		
		return null;
	}
	
	static public void copyObject(Resource r, Model fromModel, Model toModel) {
		StmtIterator si = fromModel.listStatements(r, null, (RDFNode) null);
		Resource r2 = r.isAnon() ? toModel.createResource(r.getId()) : toModel.createResource(r.getURI());
		
		while (si.hasNext()) {
			Statement 	s = si.nextStatement();
			RDFNode 	o = s.getObject();
			boolean		containedObject = toModel.containsResource(o);

			toModel.add(r2, s.getPredicate(), o);
			
			if (o instanceof Resource && !containedObject) {
				Resource r3 = (Resource) o;
				if (r3.isAnon()) {
					copyObject(r3, fromModel, toModel);
				}
			}
		}
	}
}
